package com.xyy.saas.payment.merchant.core.dto;

import com.alibaba.fastjson.JSONObject;
import com.xyy.saas.payment.adpater.fumin.config.AreaCodeManager;
import com.xyy.saas.payment.common.enums.PictureEnum;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.CertTypeEnum;
import com.xyy.saas.payment.cores.enums.FBankPowerIdEnum;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.dao.model.FmBankCode;
import com.xyy.saas.payment.util.SpringUtils;
import lombok.Data;
import lombok.extern.log4j.Log4j;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Log4j
@Data
public class CreateAllPayDto {
    //--------------基本信息--------------
    // 支付平台id
    private String userId;
    // 接口调用方的用户id
    private String businessId;
    // 接口调用方的业务类型, 支付平台分配
    private String businessIdType;
    // 账户渠道选择 目前仅支持aggregate
    private String accountChannel;
    // 回调地址
    private String callback;
    //--------------基本信息--------------
    // 商户号
    private String merchantNo;
    // 商户侧id
    private String custMerchantNo;
    // 日志流水号
    private String clientSerialNo;

    // 企业类型
    private String companyType;
    // 企业简称
    private String companyShortName;
    // 经营范围
    private String businessScope;
    // 注册资本金
    private String registeredCapital;
    // 注册资本金币种
    private String registeredCapitalCurrency;
    // 注册地址
    private String registerAddress;
    // 注册省份代码
    private String provinces;
    // 注册城市代码
    private String city;
    // 注册区县代码
    private String district;
    // 客服电话
    private String customerPhone;
    // 营业执照签发日
    private String licenseTermStart;
    // 营业执照到期日
    private String licenseTermEnd;

    // 开卡人名称
    private String accountName;
    // 卡号
    private String acct;
    // 开户行银行简称
    private String bankCd;
    // 开户支行号
    private String branchBankCd;
    // 开户支行名称
    private String branchBankName;
    // 银行预留手机号，对私时必填
    private String mobileNo;

    // 联系人名称
    private String contactName;
    // 联系人电话
    private String contactPhone;
    // 联系人邮箱
    private String contactEmail;
    // 联系人联系地址
    private String contactAddress;
    // 联系人省份代码
    private String contactProvCd;
    // 联系人城市代码
    private String contactCityCd;
    // 联系人区县代码
    private String contactContryCd;

    // 商户登陆手机号
    private String mobile;
    // 商户登陆邮箱
    private String email;

    // 法人手机号
    private String corporatePhone;
    // 法人证件签发日
    private String idCardLegalTermStart;
    // 法人证件到期日
    private String idCardLegalTermEnd;
    // 法人国籍
    private String citizenship;
    // 法人性别
    private String sex;
    // 法人户籍地址
    private String domicileAddress;
    // 法人证件签发地址
    private String issuingAddress;

    // 控股股东或者实际控制人
    private String controllerName;
    // 控股股东或者实际控制人证件种类
    private String controllerType;
    // 控股股东或者实际控制人证件号码
    private String controllerNumber;
    // 控股股东或实际控制人身份证签发日
    private String controllerStart;
    // 控股股东或实际控制人身份证到期日
    private String controllerEnd;

    // 受益人名称
    private String favoreeName;
    // 受益所有人身份证件种类
    private String favoreeType;
    // 受益所有人身份证件号码
    private String favoreeNumber;
    // 受益所有人身份证件签发日期
    private String favoreeStart;
    // 受益所有人身份证件到期日期
    private String favoreeEnd;
    // 受益所有人身份证件签发地址
    private String favoreeAddress;

    //--------------图片信息--------------
    // 门头照（企业进件必传）
    private String shopEntrancePic;
    // 营业执照（企业进件必传）
    private String businessLicensePic;
    // 开户许可证（企业进件必传）
    private String openAccountPic;
    // 法人身份证正面（企业进件必传）
    private String idCardLegalZPic;
    // 法人身份证反面（企业进件必传）
    private String idCardLegalFPic;

    // 冗余字段 - 开支付功能信息
    List<OpenPayDto> openPayList;

    /**
     * 组装JSON请求参数
     * @return
     */
    public String getJSONStringParam() throws PaymentException {
        AreaCodeManager areaCodeManager = SpringUtils.getBean("areaCodeManager", AreaCodeManager.class);
        JSONObject object = new JSONObject();
        object.put("merchant_no", getMerchantNo());
        object.put("cust_merchant_no", getCustMerchantNo());
        object.put("client_serial_no", getClientSerialNo());
        // 商户级别：1:企业；2:个体工商户
        object.put("merchant_category_code", "1");
        object.put("company_type", getCompanyType());
        object.put("business_scope", getBusinessScope());
        object.put("registered_capital", getRegisteredCapital());
        object.put("registered_capital_currency", getRegisteredCapitalCurrency());
        object.put("register_address", getRegisterAddress());
        object.put("provinces", areaCodeManager.convert2FmCode(getProvinces()));
        object.put("city", areaCodeManager.convert2FmCode(getCity()));
        object.put("district", areaCodeManager.convert2FmCode(getDistrict()));
        object.put("customer_phone", getCustomerPhone());
        object.put("license_term_start", getLicenseTermStart());
        object.put("license_term_end", getLicenseTermEnd());
        object.put("account_name", getAccountName());
        object.put("acct", getAcct());

        // 如果code为默认 则不传
        if(StringUtils.isNotBlank(getBankCd()) && !FmBankCode.BASE_BANK_SHORT_NAME.equals(getBankCd())) {
            object.put("bank_cd", getBankCd());
        }
        // 支行必填
        if(StringUtils.isBlank(getBranchBankCd())) {
            throw new PaymentException("支行信息不能为空!");
        }
        object.put("branch_bank_cd", getBranchBankCd());

        object.put("branch_bank_name", getBranchBankName());
        object.put("mobile_no", getMobileNo());
        object.put("contact_name", getContactName());
        object.put("contact_phone", getContactPhone());
        object.put("contact_email", getContactEmail());
        object.put("contact_address", getContactAddress());
        object.put("contact_prov_cd", areaCodeManager.convert2FmCode(getContactProvCd()));
        object.put("contact_city_cd", areaCodeManager.convert2FmCode(getContactCityCd()));
        object.put("contact_contry_cd", areaCodeManager.convert2FmCode(getContactContryCd()));
        object.put("mobile", getMobile());
        object.put("email", getEmail());
        object.put("corporate_phone", getCorporatePhone());
        object.put("id_card_legal_term_start", getIdCardLegalTermStart());
        object.put("id_card_legal_term_end", getIdCardLegalTermEnd());
        object.put("citizenship", getCitizenship());
        object.put("sex", getSex());
        object.put("domicile_address", getDomicileAddress());
        object.put("issuing_address", getIssuingAddress());
        object.put("controller_name", getControllerName());

        /**
         * 兼容开户的股东类型
         */
        if(CertTypeEnum.ID_CARD.getCode().equals(getControllerType())) {
            object.put("controller_type", "2");
        }
        else if(CertTypeEnum.ENTERPRISE_LICENSE.getCode().equals(getControllerType())) {
            object.put("controller_type", "1");
        }
        else {
            throw new PaymentException(ResultCodeEnum.CARD_TYPE_ERROR);
        }

        object.put("controller_number", getControllerNumber());
        object.put("controller_start", getControllerStart());
        object.put("controller_end", getControllerEnd());
        object.put("favoree_name", getFavoreeName());
        object.put("favoree_type", getFavoreeType());
        object.put("favoree_number", getFavoreeNumber());
        object.put("favoree_start", getFavoreeStart());
        object.put("favoree_end", getFavoreeEnd());
        object.put("favoree_address", getFavoreeAddress());

        if(!openPayList.isEmpty()) {
            Map<String, Object> channelPayReq = new HashMap<>();
            List<Map<String, String>> list = new ArrayList<>();
            for (OpenPayDto openPayDto : openPayList) {
                Map<String, String> map = new HashMap<>();
                map.put("power_id", openPayDto.getPowerId());
                map.put("rate", openPayDto.getRate());
                map.put("mchnt_type", openPayDto.getMchntType());
                map.put("mcc", openPayDto.getMcc());
                map.put("sub_appid", openPayDto.getSubAppid());
                if(FBankPowerIdEnum.WX_OFFICIAL.getPowerId().equals(openPayDto.getPowerId())) {
                    map.put("public_name", openPayDto.getAppletName());
                }
                else {
                    map.put("applet_name", openPayDto.getAppletName());
                }
                list.add(map);
            }
            String mchntShortName = openPayList.stream().map(OpenPayDto::getMchntShortName).distinct().findFirst().get();
            channelPayReq.put("mchnt_short_name", mchntShortName);
            channelPayReq.put("power_list", list);
            object.put("channel_open_req", channelPayReq);
        }
        return object.toJSONString();
    }

    /**
     * 组装图片列表
     * @return
     */
    public Map<String, String> getPicMap() {
        Map<String, String> pics = new HashMap<>();
        pics.put(PictureEnum.SHOP_ENTRANCE_PIC.getName(), getShopEntrancePic());
        pics.put(PictureEnum.BUSINESS_CERT_PIC.getName(), getBusinessLicensePic());
        pics.put(PictureEnum.OPEN_ACCOUNT_PIC.getName(), getOpenAccountPic());
        pics.put(PictureEnum.LEGAL_CERT_FRONT.getName(), getIdCardLegalZPic());
        pics.put(PictureEnum.LEGAL_CERT_BACK.getName(), getIdCardLegalFPic());
        return pics;
    }

    /**
     * 营业执照信息
     * @return
     */
    public String getBusinessLicenseInfo() {
        JSONObject object = new JSONObject();
        object.put("companyType", getCompanyType());
        object.put("companyShortName", getCompanyShortName());
        object.put("businessScope", getBusinessScope());
        object.put("registeredCapital", getRegisteredCapital());
        object.put("registerAddress", getRegisterAddress());
        object.put("provinces", getProvinces());
        object.put("city", getCity());
        object.put("district", getDistrict());
        object.put("customerPhone", getCustomerPhone());
        object.put("licenseTermStart", getLicenseTermStart());
        object.put("licenseTermEnd", getLicenseTermEnd());
        return object.toJSONString();
    }

    /**
     * 结算信息
     * @return
     */
    public String getSettleInfo() {
        JSONObject object = new JSONObject();
        object.put("accountName", getAccountName());
        object.put("acct", getAcct());
        object.put("bankCd", getBankCd());
        object.put("branchBankCd", getBranchBankCd());
        object.put("branchBankName", getBranchBankName());
        object.put("mobileNo", getMobileNo());
        return object.toJSONString();
    }

    /**
     * 联系人信息
     */
    public String getContactInfo() {
        JSONObject object = new JSONObject();
        object.put("contactName", getContactName());
        object.put("contactPhone", getContactPhone());
        object.put("contactEmail", getContactEmail());
        object.put("contactAddress", getContactAddress());
        object.put("contactProvCd", getContactProvCd());
        object.put("contactCityCd", getContactCityCd());
        object.put("contactContryCd", getContactContryCd());
        return object.toJSONString();
    }

    /**
     * 商家账号信息
     */
    public String getAccountInfo() {
        JSONObject object = new JSONObject();
        object.put("mobile", getMobileNo());
        object.put("email", getEmail());
        return object.toJSONString();
    }

    /**
     * 法人信息
     */
    public String getLegalInfo() {
        JSONObject object = new JSONObject();
        object.put("corporatePhone", getContactPhone());
        object.put("idCardLegalTermStart", getIdCardLegalTermStart());
        object.put("idCardLegalTermEnd", getIdCardLegalTermEnd());
        object.put("citizenship", getCitizenship());
        object.put("sex", getSex());
        object.put("domicileAddress", getDomicileAddress());
        object.put("issuingAddress", getIssuingAddress());
        return object.toJSONString();
    }

    /**
     * 股东信息
     * @return
     */
    public String getShareholderInfo() {
        JSONObject object = new JSONObject();
        object.put("controllerName", getControllerName());
        object.put("controllerType", getControllerType());
        object.put("controllerNumber", getControllerNumber());
        object.put("controllerStart", getControllerStart());
        object.put("controllerEnd", getControllerEnd());
        return object.toJSONString();
    }

    /**
     * 受益人信息
     */
    public String getBeneficiaryInfo() {
        JSONObject object = new JSONObject();
        object.put("favoreeName", getFavoreeName());
        object.put("favoreeType", getFavoreeType());
        object.put("favoreeNumber", getFavoreeNumber());
        object.put("favoreeStart", getFavoreeStart());
        object.put("favoreeEnd", getFavoreeEnd());
        object.put("favoreeAddress", getFavoreeAddress());
        return object.toJSONString();
    }

    /**
     * 图片信息
     */
    public String getimgsInfo() {
        JSONObject object = new JSONObject();
        object.put("shopEntrancePic", getShopEntrancePic());
        object.put("businessLicensePic", getBusinessLicensePic());
        object.put("openAccountPic", getOpenAccountPic());
        object.put("idCardLegalZPic", getIdCardLegalZPic());
        object.put("idCardLegalFPic", getIdCardLegalFPic());
        return object.toJSONString();
    }
}
